import s from './index.module.scss';
import { useEffect, useRef, useState } from 'react';
import Pagination from './components/pagination';

const transitionContent = 'all 200ms ease-in';
const transitionLoop = 'all 400ms ease-in';

const Sliders = (props) => {
  const slidersRef = useRef(null);

  const [containerLeft, setContainerLeft] = useState(0);
  const [oldContainerLeft, setOldContainerLeft] = useState(0);
  const [len, setLen] = useState(0);
  const [width, setWidth] = useState(0);
  const [touchX, setTouchX] = useState(0);
  const [percentage, setPercentage] = useState(0);
  const [activeIndex, setActiveIndex] = useState(0);
  const [direction, setDirection] = useState(1);
  const [isShowTrans, setIsShowTrans] = useState(false);
  const [moving, setMoving] = useState(false);
  const [movingId, setMovingId] = useState(null);

  const slidersScrolllCB = () => {
    const sliderItemWidth =
      slidersRef.current.children[0]?.getBoundingClientRect().width;
    const x = slidersRef.current.getBoundingClientRect().x;
  };

  const start = (e) => {
    const touch = e.touches[0];
    setTouchX(touch.clientX);
    setOldContainerLeft(containerLeft);
    setMoving(true);
  };

  const move = (e) => {
    const offset = touchX - e.touches[0].clientX;
    if (offset >= 0) {
      setDirection(1);
    } else {
      setDirection(-1);
    }
    const percent =
      Math.abs(offset / width) >= 0.3 ? 0.3 : Math.abs(offset / width);
    setPercentage(percent);

    const distance = oldContainerLeft - offset;
    if (
      !(activeIndex === 0 && offset < 0) &&
      !(activeIndex === len - 1 && offset > 0)
    ) {
      setContainerLeft(distance);
    }
  };

  const end = (e) => {
    if (percentage === 0.3 && direction === 1 && activeIndex < len - 1) {
      setIsShowTrans(true);
      setActiveIndex(activeIndex + 1);
      setContainerLeft(-width * (activeIndex + 1));
    } else if (percentage === 0.3 && direction === -1 && activeIndex > 0) {
      setIsShowTrans(true);
      setActiveIndex(activeIndex - 1);
      setContainerLeft(-width * (activeIndex - 1));
    } else {
      if (oldContainerLeft !== containerLeft) {
        setIsShowTrans(true);
      }
      setContainerLeft(oldContainerLeft);
    }
    setMoving(false);
  };

  const transitionEndCB = () => {
    setIsShowTrans(false);
  };

  const nextSlider = (l, w, i) => {
    if (i > l - 1) {
      setActiveIndex(0);
      setContainerLeft(0);
    } else {
      setActiveIndex(i);
      setContainerLeft(-w * i);
    }
  };

  const handleLoop = (l, w, i) => {
    let newMovingId = movingId;
    i = i || activeIndex || 0;
    if (!moving && newMovingId === null) {
      newMovingId = setInterval(() => {
        nextSlider(l, w, i);
        if (i > l - 1) {
          i = 0;
        } else {
          i++;
        }
      }, props.duration);
      setMovingId(newMovingId);
    } else if (moving) {
      clearInterval(newMovingId);
      setMovingId(null);
    }
  };

  const changeSilder = (index) => {
    clearInterval(movingId);
    setMovingId(null);
    nextSlider(len, width, index);
  };

  useEffect(() => {
    slidersRef?.current.addEventListener('touchstart', start, {
      passive: true,
    });
    slidersRef?.current.addEventListener('touchmove', move, { passive: true });
    slidersRef?.current.addEventListener('touchend', end, { passive: true });
    slidersRef?.current.addEventListener('transitionend', transitionEndCB);

    return () => {
      slidersRef?.current.removeEventListener('touchstart', start);
      slidersRef?.current.removeEventListener('touchmove', move);
      slidersRef?.current.removeEventListener('touchend', end);
      slidersRef?.current.removeEventListener('transitionend', transitionEndCB);
    };
  }, [
    touchX,
    percentage,
    containerLeft,
    activeIndex,
    oldContainerLeft,
    isShowTrans,
  ]);

  useEffect(() => {
    setWidth(slidersRef.current.children[0]?.getBoundingClientRect().width);
    setLen(slidersRef.current.children?.length);
  }, []);

  useEffect(() => {
    handleLoop(
      slidersRef.current.children?.length,
      slidersRef.current.children[0]?.getBoundingClientRect().width
    );
  }, [moving, movingId]);

  return (
    <div className={s.wrapper}>
      <div
        ref={slidersRef}
        className={s.container}
        style={{
          '--containerWidth': width * len + 'px',
          '--containerLeft': containerLeft + 'px',
          // transition: isShowTrans ? transitionContent : 'none',
          transition: !moving ? transitionLoop : 'none',
        }}
      >
        {props.children}
      </div>
      <Pagination
        len={len}
        activeIndex={activeIndex}
        changeSilder={changeSilder}
      />
    </div>
  );
};

export default Sliders;
